package com.autonavi.abs.generator.util;

import com.autonavi.abs.generator.common.Constant;
import com.autonavi.abs.generator.common.enumeration.MetaDataKeyEnum;
import com.autonavi.abs.generator.common.model.ColumnMeta;
import com.autonavi.abs.generator.common.model.TableMeta;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author tianquan.ld
 * @version V1.0
 * <p>Description: db工具类</p>
 * @date 2020-08-10 17:25
 */
@Slf4j
public class DbUtil {

    /**
     * 获取解析后的table list
     *
     * @param connection
     * @return
     * @throws Exception
     */
    public static List<TableMeta> getTableList(Connection connection) throws Exception {

        List<TableMeta> tableMetaList = new ArrayList<>();
        ResultSet resultSet = null;
        try {

            log.info("开始读取table列表...");
            DatabaseMetaData metaData = connection.getMetaData();
            resultSet = metaData.getTables(null, null, Constant.PERCENT, null);

            tableMetaList = parseTableList(resultSet);
            log.info("完成读取table列表...");
        } catch (Exception e) {
            log.error("读取table列表异常...");
            log.error(e.getMessage(), e);
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
        return tableMetaList;
    }

    /**
     * 获取解析后的数据库字段list
     *
     * @param connection
     * @return
     * @throws Exception
     */
    public static List<ColumnMeta> getColumnList(Connection connection, String tableName) throws Exception {

        List<ColumnMeta> columnList = new ArrayList<>();
        ResultSet resultSet = null;
        try {

            log.info("开始读取表{}元数据...",tableName);
            DatabaseMetaData metaData = connection.getMetaData();
            resultSet = metaData.getColumns(null, Constant.PERCENT, tableName, Constant.PERCENT);

            columnList = parseColumnList(resultSet);

            markPrimaryKey(metaData, tableName, columnList);
            log.info("完成读取表{}元数据...",tableName);
        } catch (Exception e) {
            log.info("读取表{}元数据异常...",tableName);
            log.error(e.getMessage(), e);
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
        return columnList;
    }

    /**
     * 解析元数据
     *
     * @param resultSet
     * @return
     * @throws SQLException
     */
    private static List<ColumnMeta> parseColumnList(ResultSet resultSet) throws SQLException {

        List<ColumnMeta> columnList = new ArrayList<>();
        if (resultSet == null) {
            return columnList;
        }

        //获取所有字段
        while (resultSet.next()) {

            ColumnMeta column = new ColumnMeta();
            //获取字段名称
            column.setName(resultSet.getString(MetaDataKeyEnum.COLUMN_NAME.name()));
            //获取字段类型
            column.setJdbcType(resultSet.getString(MetaDataKeyEnum.TYPE_NAME.name()));
            //字段在数据库的注释
            column.setComment(resultSet.getString(MetaDataKeyEnum.REMARKS.name()));
            //是否允许为空
            column.setNullAble(resultSet.getInt(MetaDataKeyEnum.NULLABLE.name()));

            //转换字段名称，如 sys_name 变成 SysName
            column.setCamelName(StringUtil.getCamelName(column.getName()));
            column.setUpperName(StringUtil.getFirstUpperCaseFromUnderLine(column.getCamelName()));
            columnList.add(column);
        }
        return columnList;
    }

    /**
     * 解析table数据
     *
     * @param resultSet
     * @return
     * @throws SQLException
     */
    private static List<TableMeta> parseTableList(ResultSet resultSet) throws SQLException {

        List<TableMeta> columnList = new ArrayList<>();
        if (resultSet == null) {
            return columnList;
        }

        //获取所有字段
        while (resultSet.next()) {

            TableMeta tableMeta = new TableMeta();
            //获取字段名称
            tableMeta.setName(resultSet.getString(MetaDataKeyEnum.TABLE_NAME.name()));
            tableMeta.setComment(resultSet.getString(MetaDataKeyEnum.REMARKS.name()));
            tableMeta.setCamelName(StringUtil.getCamelName(tableMeta.getName()));
            tableMeta.setUpperName(StringUtil.getFirstUpperCaseFromUnderLine(tableMeta.getCamelName()));
            columnList.add(tableMeta);

        }
        return columnList;
    }

    /**
     * 标记主键
     *
     * @param metaData
     * @param tableName
     * @param columnList
     * @throws SQLException
     */
    private static void markPrimaryKey(DatabaseMetaData metaData, String tableName, List<ColumnMeta> columnList) throws SQLException {

        if (CollectionUtils.isEmpty(columnList)) {
            return;
        }

        //标记主键
        ResultSet primaryResultSet = metaData.getPrimaryKeys(null, null, tableName);
        String primaryKeyName = null;
        while (primaryResultSet.next()) {
            primaryKeyName = primaryResultSet.getString(MetaDataKeyEnum.COLUMN_NAME.name());
        }
        if (StringUtils.isNotBlank(primaryKeyName)) {
            for (ColumnMeta column : columnList) {
                if (column.getName().equals(primaryKeyName)) {
                    column.setPrimaryKey(Constant.TRUE);
                } else {
                    column.setPrimaryKey(Constant.FALSE);
                }
            }
        }
    }

}
